package javaeSE;

/*   多态 与 抽象类的使用    多态基础
     说明: 多态存在的条件  =>  继承和重写
     父类引用指向子类对象：Parent p = new Child();   属性是没有多态的  只看左边 Animal a */
public class Variable {
    public static void main(String[] args) {
        show(new Cat());  // 以 Cat 对象调用 show 方法
        show(new Dog());  // 以 Dog 对象调用 show 方法
        // 父类引用指向子类对象 就叫多态   一般多态都是用于调父类有的，子类重写的方法☆☆☆☆☆
        Animal a = new Cat();  // 向上转型  (实例化仍然是猫动物的实例，动物本身又eat方法,所以可以直接调)  90%
        a.eat();               // 调用的是 Cat(子类的) 同名 eat  此时父类的eat叫虚拟方法
        a.sleep();              // 可以调 父类有的方法与属性
        System.out.println(a.size);
        //  a.teyou();         不能调cat里独有的方法 因为本质还是animal类实例(编译看左)，右侧调的是cat中重写的父类同名方法  运行看右
        Cat c = (Cat)a;        // 向下转型  (动物类 调猫独有的方法或者属性都要转成猫  子类)
        c.work();        // 调用的是 Cat 的 work

        Animal dog = new Dog(); // 不能把上面的a 再去转dog   Dog dogs = (Dog)a 错误写法
        Dog dogs = (Dog)dog ;

        dogs.sleep();
    }

    public static void show(Animal a)  {
        // 共有方法
        a.eat();
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 已经是猫了 转成猫=>调猫自己的方法
            Cat c = (Cat)a;
            c.work();
        } else if (a instanceof Dog) { // 狗做的事情 已经是狗了 转成狗=>调狗自己的方法
            Dog c = (Dog)a;
            c.work();
        }
    }
}


abstract class Animal {
    public int size =20;
    public String type;

    abstract void eat();
    abstract void sleep();
}

class Cat extends Animal {
    // 任何子类必须重写父类的抽象方法，或者声明自身为抽象类
    public void eat() {
        System.out.println("吃鱼");
    }
    public void work() {
        System.out.println("抓老鼠");
    }
    public void sleep() {
        System.out.println("=睡觉");
    }
    public void teyou(){
        System.out.println("animal 自己有的方法");
    }
}

class Dog extends Animal {
    // 任何子类必须重写父类的抽象方法，或者声明自身为抽象类
    public void eat() {
        System.out.println("吃骨头");
    }
    public void work() {
        System.out.println("看家");
    }
    public void sleep() {
        System.out.println("狗睡觉2");
    }
}